dojo.provide('snareworks.MathGrid');

dojo.require('snareworks.MGUtils');
dojo.require('snareworks.SoundUtils');
dojo.require('snareworks.ImageUtils');

dojo.require('dojo.fx');

dojo.declare("snareworks.MathGrid", null, {
	
	NUM_COLUMNS_DEFAULT: 6,
	NUM_COLUMNS: 6,
	
	COL_START_DEFAULT: 1,
	COL_START: 1,
	
	ROW_START_DEFAULT: 1,
	ROW_START: 1,
	
	current: -1,
	
	users: {
	  '969cef3f304214046504a2423b595d8f': {name: 'Steve', 
			showControls: false, colStart: 1, rowStart: 1, 
			numRows: 5, operation: 'addition'},
	  'eb0c273f38ee3784302fa2143a505884': {name: 'Kayla', 
			showControls: false, colStart: 1, rowStart: 1, 
			numRows: 10, operation: 'multiplication'},
	  '21232f297a57a5a743894a0e4a801fc3': {name: 'Admin', showControls: true, colStart: 1, rowStart: 1, numRows: 10, operation: 'addition'}
	},
	
	OPERATIONS: {
		multiplication: {label: 'times', id:'multiplication', symbol:'x'},
		addition: {label: 'plus', id:'addition', symbol:'+'},
		subtraction: {label: 'minus', id:'subtraction', symbol:'-'}
	},
	
	constructor: function() {
		this.OPERATIONS.multiplication.fx = dojo.hitch(this, 'multiply');
		this.OPERATIONS.addition.fx = dojo.hitch(this, 'add');
		this.OPERATIONS.subtraction.fx = dojo.hitch(this, 'subtract');
		this.OPERATION = this.OPERATIONS.multiplication;
	},
	
	initialize: function() {
		this.su = new snareworks.SoundUtils();
		this.iu = new snareworks.ImageUtils();
		this.mg = new snareworks.MGUtils();
		var local = window.location.href.indexOf('file:') == 0;
		if (local) {
			dojo.style(dojo.byId('game'), 'display', 'block');
			dojo.style(dojo.byId('controls'), 'display', 'block');
			dojo.style(dojo.byId('login'), 'display', 'none');
			dijit.byId('loginBox').attr('value', 'admin');
			this.initializeGame();
		} else {
			dojo.style(dojo.byId('login'), 'display', 'block');
		}
	},
	
	login: function(e) {
		if (e.keyCode == dojo.keys.ENTER) {
			var loginBox = dijit.byId('loginBox');
			if (loginBox) {
				var code = loginBox.attr('value');
				var hash = this.mg.getMD5Hash(code.toLowerCase());
				var user = this.users[hash];
				if (user) {
					dojo.style(dojo.byId('login'), 'display', 'none');
					dijit.byId('numRowsInput').attr('value', user.numRows);
					dijit.byId('colInput').attr('value', user.colStart);
					dijit.byId('rowInput').attr('value', user.rowStart);
					var radio = dijit.byId(user.operation);
					if (radio) {
						radio.attr('checked', true);
					}
					if (user.showControls) {
						dojo.style(dojo.byId('controls'), 'display', 'block');
					}
					this.initializeGame();
				} else {
					dojo.style(dojo.byId('loginMessage'), 'display', 'inline');
					dijit.byId('loginBox').attr('value', '');
				}
			} else {
				alert("Dad messed up.  Something's wrong.");
			}
		}
	},
	
	initializeGame: function() {
		
		dojo.style(dojo.byId('game'), 'display', 'block');
		
		this.OPERATION = this.getSelectedOperation();
		this.NUM_COLUMNS = this.getIntFromInput('numRowsInput', this.NUM_COLUMNS_DEFAULT);
		this.ROW_START = this.getIntFromInput('rowInput', this.ROW_START_DEFAULT);
		this.COL_START = this.getIntFromInput('colInput', this.COL_START_DEFAULT);
		
		var table = dojo.byId('gridTable');
//		table.innerHTML = ""; // not in IE...
		while (table.firstChild) {
			table.removeChild(table.firstChild);
		}
		this.current = -1;
		
		var tbody = document.createElement('tbody');
		table.appendChild(tbody);
		
		if (this.OPERATION == this.OPERATIONS.subtraction) {
			this.ROW_START = this.COL_START + this.NUM_COLUMNS - 1;
		}
		
		var row = document.createElement("tr");
		var message = dojo.byId("message");
		if (message) message.innerHTML = '';
		for (var i = this.COL_START - 1; i < this.NUM_COLUMNS + this.COL_START; i++) {
			var cell = document.createElement("td");
			if (i > this.COL_START - 1) {
				cell.innerHTML = "" + i;
				cell.className = 'colLabel';
			} else {
				cell.className = 'noBorder opercell';
				cell.innerHTML = this.OPERATION.symbol;
			}
			cell.className += ' td';
			row.appendChild(cell);
		}
		tbody.appendChild(row);
		this.answers = [];
//		
//		// num_columns + 1 to allow for a column of row labels.
		for (var r = this.ROW_START; r < this.NUM_COLUMNS + this.ROW_START; r++) {
			var row = document.createElement("tr");
			for (var c = this.COL_START - 1; c < this.NUM_COLUMNS + this.COL_START; c++) {
				var cell = document.createElement("td");
				if (c == this.COL_START - 1) {
					cell.innerHTML = "" + r;
					cell.className = 'rowLabel';
				} else {
					cell.innerHTML = "&nbsp;";
					cell.className = "valueCell unsolved";
					cell.id = r + "_" + c;
					var answer = {
						answer: this.OPERATION.fx(r, c),
						row: r,
						col: c,
						id: cell.id,
						cell: cell,
						success: false
					};
					this.answers.push(answer);
					cell.answer = answer;
				}
				cell.className += ' td';
				row.appendChild(cell);
			}
			tbody.appendChild(row);
		}
		
		this.mg.shuffle(this.answers);
		this.nextQuestion();
	},
	
	nextQuestion: function() {
		this.current++;
		dojo.query('.rowIndicator').removeClass('rowIndicator');
		dojo.query('.colIndicator').removeClass('colIndicator');
		dojo.query('.active').removeClass('active');

		var answerBox = dijit.byId('answerBox');
		if (this.current == this.answers.length) {
			this.su.playMP3(this.su.COMPLETE_SOUND);
			dojo.cookie("MathGridCookie", '1');
			var msg = 'Great Job!!!  You got them all right!!!\n\n';
			alert(msg);
			window.location.reload(true);
		} else {
			var answer = this.answers[this.current];
			this.animateQuestion('What is ' + answer.row + ' ' + this.OPERATION.label + ' ' + answer.col + '?');
			dojo.addClass(dojo.byId(this.answers[this.current].id), 'active');
			answerBox.attr('value', '');
			dojo.query('[id*="' + answer.row + '_"]').forEach(function(cell){
				if (cell.answer && cell.answer.col < answer.col) {
					dojo.addClass(cell, 'rowIndicator');
				}
			});
			dojo.query('[id*="_' + answer.col + '"]').forEach(function(cell){
				if (cell.answer && cell.answer.row < answer.row) {
					dojo.addClass(cell, 'colIndicator');
				}
			});
		}
		answerBox.attr('disabled', false);
		answerBox.focus();
		this.updateCounts();
	},
	
	animateQuestion: function(q) {
		var qNode = dojo.byId('question');
		var f = function() {
			qNode.innerHTML = q;
		};
		var fadeOut = dojo.fadeOut({node: qNode, duration: 500, onEnd:f});
		var fadeIn = dojo.fadeIn({node: qNode, duration: 500});
		dojo.fx.chain([fadeOut, fadeIn]).play();
	},
	
	keyPressed: function(e) {
		var input = dijit.byId('answerBox');
		if (!input.attr('disabled') && e.keyCode == dojo.keys.ENTER) {
			var answer = this.answers[this.current];
			
			input.attr('disabled', true);
			var message = dojo.byId('message');
			dojo.removeClass(message, 'correct');
			dojo.removeClass(message, 'incorrect');
			var cell = dojo.byId(answer.id);
			var image = null;
			if (input.attr('value') == answer.answer + '') {
				dojo.addClass(message, 'correct');
				message.innerHTML = "Correct!  " + answer.row + " " + this.OPERATION.label + " " + answer.col + ' equals ' + answer.answer + '.';
				dojo.removeClass(cell, 'unsolved');
				dojo.removeClass(cell, 'active');
				dojo.addClass(cell, 'solved');
				image = this.iu.nextRightImage();
				if (this.current < this.answers.length - 1) {
					this.su.playRightSound();
				}
				goToNextQuestion = true;
			} else {
				this.current--;
				var image = this.iu.nextWrongImage();
				dojo.addClass(message, 'incorrect');
				message.innerHTML = "Sorry. " + answer.row + " " + this.OPERATION.label + " " + answer.col + ' does not equal ' + input.attr('value') + '.';;
				this.su.playWrongSound();
				input.attr('value', '');
			}
			while (cell.firstChild) cell.removeChild(cell.firstChild);
			cell.appendChild(image);
			// now animate it...
			var cb = this;
			var endHandler = function(){
					cb.nextQuestion();
			};
			dojo.animateProperty(
			    {
			      node: image,
			      duration: 1000,
			      properties: {
			        width: {end: 60},
			        height: {end: 60}
			      },
			      onEnd: endHandler
			    }).play();
			e.preventDefault();
		}
	},
	
	updateCounts: function() {
		this.updateCount('numDone', this.current, 'done!!!');
		this.updateCount('numLeft', this.answers.length - this.current, 'to go!!!');
	},
	
	updateCount: function(id, val, str) {
		var fullDiv = dojo.byId(id + 'Div');
		
		var msg = val + ' problem';
		if (val != 1) {
			msg += 's';
		}
		msg += ' ' + str;
		
		fullDiv.innerHTML = msg;
				
		var rules = dojo.isIE ? 'rules' : 'cssRules';
		var index = dojo.isIE ? 0 : 2;
		
		var bgEnd = document.styleSheets[0][rules][index].style.backgroundColor;
		
		dojo.animateProperty({
			node:fullDiv,
			duration:2000,
			properties: {
				backgroundColor: { start: "yellow", end:bgEnd }
			}
		}).play();
	},

	add: function(x, y) {
		return x + y;
	},
	
	subtract: function(x, y) {
		return x - y;
	},
	
	multiply: function(x, y) {
		return x * y;
	},
	
	updateOperation: function() {
		if (this.current == 0 || (this.current > 0 && confirm("Are you sure you want to quit and start over?"))) {
			this.initializeGame();
		}
	},
	
	getSelectedOperation: function() {
		var op = null;
		for (var operationName in this.OPERATIONS) {
			var operation = this.OPERATIONS[operationName];
			if (dijit.byId(operation.id).checked) {
				op = operation;
			}
		}
		return op;
	},
	
	getIntFromInput: function(id, defVal) {
		var val = defVal;
		var input = dijit.byId(id);
		if (input) {
			var sVal = input.attr('value');
			var iVal = parseInt(sVal);
			if (!isNaN(iVal)) {
				val = iVal;
			}
		}
		return val;
	}
	
});
